﻿using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using SoftwareConsulting.BI11.Studio.InternalServices;
using SoftwareConsulting.BI11.Studio.ProcessWait.Properties;

[assembly:CLSCompliant(true)]
namespace SoftwareConsulting.BI11.Studio.ProcessWait
{
    /// <summary>
    /// Класс аргументов события изменения прогресса
    /// </summary>
    public class ProgressEventArgs : EventArgs
    {
        private int _progress; //прогресс в процентах

        /// <summary>
        /// Возвращает прогресс в процентах
        /// </summary>
        public int Progress
        {
            get
            {
                return _progress;
            }
        }

        /// <summary>
        /// Конструктор класса
        /// </summary>
        /// <param name="progress">прогресс в процентах</param>
        public ProgressEventArgs(int progress)
            : base()
        {
            _progress = progress;
        }
    }

    /// <summary>
    /// Делегат на изменение прогресса
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="args"></param>
    public delegate void ProgressEvent(object sender, ProgressEventArgs args);

    /// <summary>
    /// Класс, реализующий окно ожидания в интерфейсе
    /// </summary>
    public static class Processing
    {
        //public static Form parentForm; //родительская форма
        private static bool _killThread = false;//убить поток формы ожидания
        private static bool _showPercent = false;//показать процентную строку        
        private static int _percent = 0;//текущий процент
        private static bool _updateDescription = false;//обновить описание
        private static string _description = "";//текущее описание
        private static ProcessForm _processform;//форма ожидания
        private static Thread _processFormThread;//поток формы ожидания

        /*public static ProcessForm processform
        {
            get
            {
                return _processform;
            }
            set
            {
                _processform = value;
            }
        }*/

        /// <summary>
        /// Обновляет форму ожидания
        /// </summary>
        private static void UpdateProcessForm()
        {
            _processform = new ProcessForm();//parentForm);
            _processform.Show();
            if (!_processform.IsLoaded)
            {
                _processform.Refresh();
            }
            DateTime lastUpdate = DateTime.Now;
            while (!_killThread)
            {
                bool refreshRightNow = false;
                if (_showPercent)
                {
                    _showPercent = false;
                    if (!_processform.ProgressVisible)
                    {
                        _processform.ProgressVisible = true;
                    }
                    _processform.Progress = _percent;
                    if (_percent == 100)
                    {
                        SetDescription("");
                    }
                    refreshRightNow = true;
                }
                if (_updateDescription)
                {
                    _updateDescription = false;
                    _processform.Description = _description;
                    refreshRightNow = true;
                }
                if (refreshRightNow || ((DateTime.Now - lastUpdate).TotalSeconds > 3))                
                {
                    _processform.Refresh();
                    lastUpdate = DateTime.Now;
                }
                //Thread.CurrentThread.Join(50);
            }
            _killThread = false;
            _processform.Close();
            _processform.Dispose();
            _processform = null;
        }

        /// <summary>
        /// Отображает форму ожидания
        /// </summary>
        public static void BeginWait()
        {
            EndWait();            
            _processFormThread = new Thread(UpdateProcessForm);
            _processFormThread.IsBackground = true;
            _killThread = false;
            _processFormThread.Start();                   
        }

        /// <summary>
        /// Убирает форму ожидания
        /// </summary>
        public static void EndWait()
        {
            //if (_processform != null)
            {
                _killThread = true;
                if (_processFormThread != null)                
                {
                    _processFormThread.Join(3000);
                }
                /*_processFormThread.Abort();
                _processFormThread = null;
                _processform.Dispose();
                _processform = null;*/
            }
        }

        /// <summary>
        /// Отображает процентную строку с указанным значением процентов
        /// </summary>
        /// <param name="percent"></param>
        public static void ShowPercent(int percent)
        {
            _percent = percent;
            _showPercent = true;
            /*if (!_processform.ProgressVisible)
            {
                _processform.ProgressVisible = true;
            }
            _processform.Progress = percent;
            if (percent == 100)
            {
                SetDescription("");
            }*/
        }

        /// <summary>
        /// Устанавливает в качестве текущего процента необходимое значение с учетом того, что это значение является процентом лишь от части процентной строки
        /// </summary>
        /// <param name="percent">значение процента</param>
        /// <param name="leftPercentBorderOfPart">левая граница части процентной строки</param>
        /// <param name="rightPercentBorderOfPart">правая граница части процентной строки</param>
        public static void SetPercentOfPartByBorders(int percent, int leftPercentBorderOfPart, int rightPercentBorderOfPart)
        {
            int length = rightPercentBorderOfPart - leftPercentBorderOfPart;
            ShowPercent(Convert.ToInt32(percent * length / 100) + leftPercentBorderOfPart);
        }

        /// <summary>
        /// Устанавливает описание операции
        /// </summary>
        /// <param name="description"></param>
        /// <remarks>если описание установлено пустым, то строка
        /// с описанием скрывается</remarks>
        public static void SetDescription(string description)
        {
            _description = description;
            _updateDescription = true;
            /*if (_processform != null)
            {
                _processform.Description = desc;
            }*/
        }

        /// <summary>
        /// Отображает сообщение о том, что операция завершена успешно
        /// </summary>
        public static void WellDone()
        {
            SetDescription("");
            GeneralMethods.ShowInformation(Resources.BI_MESSAGE_OPERATIONDONE);            
        }

        /*
        public static void SetPercentOfPartByLength(int percent, int maxlength)
        {
            int curval = processform.Progress;
            SetPercentOfPartByBorders(percent, curval, curval + maxlength);
        }*/
    }
}
